/**
 * Created by 七星瓢虫 on 2021-06-13 20:55:54.
 */
module CommandExecute {
    /**
     * 自定义播放音频
     */
    export function customCommand_15001(commandPage: CommandPage, cmd: Command, trigger: CommandTrigger, triggerPlayer: ClientPlayer, playerInput: any[], p: CustomCommandParams_15001): void {
        // 分析获取的音频
        if (!p.filePath) return null;
        let filePathArr: any[] = p.filePath.split(",");
        let url: string = filePathArr[0];
        if (!url) return null;
        let volume = filePathArr[1] != null ? MathUtils.float(filePathArr[1]) : 1;
        let pitch = filePathArr[2] != null ? MathUtils.float(filePathArr[2]) : 1;
        p.gradientInTime = p.gradientInTime != null ? p.gradientInTime : 0;
        p.gradientOutTime = p.gradientOutTime != null ? p.gradientOutTime : 0;
        // 定义变量
        let startVolume = p.gradientInTime > 0 ? 0 : volume; // 起始的音量，淡入时生效
        let endVolume = p.gradientOutTime > 0 ? 0 : volume; // 结束的音量，淡出时生效
        let lastPlayedTime; // 已播时间
        let startTime2; // 开始时间2 等于 已播时间 加 开始时间
        let duration; // 总时长(没有旧的就为无限大)
        let endTime2; // 结束时间2 等于 总时长 和 结束时间 中较小的一个
        // 预加载
        AssetManager.loadAudio(url, Callback.New(() => {
            // 根据音频类别进行差分
            if (p.audioType == 0) {
                // 已播时间
                lastPlayedTime = (GameAudio.lastBgmSoundChannel != null && GameAudio.lastBgmURL == url) ? GameAudio.lastBgmSoundChannel.position : 0;
                // 开始时间2 等于 已播时间 加 开始时间
                startTime2 = lastPlayedTime + p.startTime;
                // 总时长(没有旧的就为无限大)
                duration = (GameAudio.lastBgmSoundChannel != null && GameAudio.lastBgmURL == url) ? GameAudio.lastBgmSoundChannel.duration : Number.POSITIVE_INFINITY;
                // 结束时间2 等于 总时长 和 结束时间 中较小的一个
                endTime2 = p.endTime > 0 ? Math.min(duration, p.endTime) : duration;
                // 开始时间2 大于 结束时间2 的情况
                if (GameAudio.lastBgmSoundChannel && startTime2 > endTime2) {
                    if (p.overTimeChoose == 0) startTime2 = 0; // 从头播放
                    else if (p.overTimeChoose == 1) return null; // 不播放
                    else startTime2 = startTime2 % GameAudio.lastBgmSoundChannel.duration; // 自动取余
                }
                // 清除原先的 BGM 缓动 (未开放 API)
                if (GameAudio.lastBgmTween) {
                    Tween.clear(GameAudio.lastBgmTween);
                    GameAudio.lastBgmTween = null;
                }
                // 清理原先的结束
                clearTimeout(GameAudio['lastBgmSTO']);
                clearTimeout(GameAudio['lastBgmSTO2']);
                // 同音源的处理
                if (GameAudio.lastBgmURL == url) {
                    // 中段变奏
                    if (GameAudio.lastBGMPitch != pitch) {
                        if (GameAudio.lastBgmSoundChannel) GameAudio.lastBgmSoundChannel.stop(); // 不用回收吗？
                        GameAudio.lastBgmSoundChannel = SoundManager.playSound(url, p.loopTimes, pitch, Handler.create(this, function (url, volume, pitch) {
                            // 播放完毕后，音频未发生变化时（由于旧的永远不会播放完毕，有必要判断变化与否吗?）
                            if (url == GameAudio.lastBgmURL && volume == GameAudio.lastBGMVolume && pitch == GameAudio.lastBGMPitch) {
                                GameAudio.lastBgmURL = GameAudio.lastBgsSoundChannel = null;
                                CommandPage.startTriggerFragmentEvent(p.commandsEachTime, Game.player.sceneObject, Game.player.sceneObject);
                            }
                        }, [url, volume, pitch]), null, startTime2);
                    }
                }
                else {
                    if (GameAudio.lastBgmSoundChannel) GameAudio.lastBgmSoundChannel.stop();
                    GameAudio.lastBgmSoundChannel = SoundManager.playSound(url, p.loopTimes, pitch, Handler.create(this, function (url, volume, pitch) {
                        // 播放完毕后，音频未发生变化时
                        if (url == GameAudio.lastBgmURL && volume == GameAudio.lastBGMVolume && pitch == GameAudio.lastBGMPitch) {
                            GameAudio.lastBgmURL = GameAudio.lastBgsSoundChannel = null;
                            CommandPage.startTriggerFragmentEvent(p.commandsEachTime, Game.player.sceneObject, Game.player.sceneObject);
                        }
                    }, [url, volume, pitch]), null, startTime2);
                }
                // 音量变化
                if (p.gradientInTime > 0) { // 淡入 (未开放 API)
                    GameAudio.lastBgmSoundChannel.volume = startVolume;
                    GameAudio.lastBgmTween = Tween.to(GameAudio.lastBgmSoundChannel, { volume: volume * GameAudio.bgmVolume }, p.gradientInTime * 1000, null, Callback.New(() => {
                        GameAudio.lastBgmTween = null; // 更新记录：淡入
                    }, this));
                }
                else { // 直接调音量
                    GameAudio.lastBgmSoundChannel.volume = startVolume * GameAudio.bgmVolume;
                }
                // 更新记录
                GameAudio.lastBgmURL = url; // 地址
                GameAudio.lastBGMVolume = volume; // 音量
                GameAudio.lastBGMPitch = pitch; // 音调
                // 更新不知道什么东西
                GameAudio.lastBgmSoundChannel["_selfVolume"] = volume;
                // 更新实际结束时间
                endTime2 = p.endTime > 0 ? Math.min(GameAudio.lastBgmSoundChannel.duration, p.endTime) : GameAudio.lastBgmSoundChannel.duration;
                // 提前结束和淡出
                let passGradientOutTime = endTime2 - startTime2 - p.gradientOutTime < 0 ? Math.abs(endTime2 - startTime2 - p.gradientOutTime) : 0;
                if (p.gradientOutTime > 0) GameAudio.lastBgmSoundChannel.volume = ((p.gradientOutTime - passGradientOutTime) / p.gradientOutTime) * GameAudio.lastBgmSoundChannel.volume;
                GameAudio['lastBgmSTO'] = setTimeout(() => {
                    if (url == GameAudio.lastBgmURL && volume == GameAudio.lastBGMVolume && pitch == GameAudio.lastBGMPitch) {
                        GameAudio.stopBGM(p.gradientOutTime > 0, (p.gradientOutTime - passGradientOutTime) * 1000);
                        GameAudio['lastBgmSTO2'] = setTimeout(() => {
                            CommandPage.startTriggerFragmentEvent(p.commandsEachTime, Game.player.sceneObject, Game.player.sceneObject);
                        }, (p.gradientOutTime - passGradientOutTime) * 1000);
                    }
                }, (endTime2 - startTime2 - p.gradientOutTime) * 1000);
            }
        }, this));
    }
}
